/**
 * 
 */
package com.hexacta.hrs.web.struts.actions.feedbacks;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.apache.velocity.app.VelocityEngine;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.ui.velocity.VelocityEngineUtils;
import org.vectrics.employee.Employee;

import com.hexacta.hrs.domain.feedback.Feedback;
import com.hexacta.hrs.services.feedbacks.FeedbackService;

/**
 * @author gvilla
 * 
 */
public class ReminderMailSender {

    /* Properties */
    private JavaMailSender mailSender;

    private VelocityEngine velocityEngine;

    // private SimpleMailMessage templateMessage;

    private FeedbackService feedbackService;

    /* Variables */
    private String[] roles;

    private Map<Employee, Set<Employee>> lazyEvaluators;

    public ReminderMailSender() {
        lazyEvaluators = new HashMap<Employee, Set<Employee>>();
    }

    /* Methods */

    /**
     * @throws MessagingException
     * 
     */
    public void sendReminders() throws MessagingException {

        findLazyEvaluators();
        sendMails();

    }

    /**
     * 
     */
    private void findLazyEvaluators() {
        List<Feedback> feedbacks;
        lazyEvaluators.clear();

        if (roles == null) {
            feedbacks = feedbackService.getPendingFeedbacks();
            addDistinct(feedbacks);
            return;
        }

        for (String role : roles) {
            feedbacks = feedbackService.getPendingFeedbacksForRole(role);
            addDistinct(feedbacks);
        }
    }

    /**
     * @param feedbacks
     */
    private void addDistinct(final List<Feedback> feedbacks) {
        for (Feedback feedback : feedbacks) {

            Set<Employee> remaining = lazyEvaluators.get(feedback.getEvaluator());

            if (remaining == null) {
                remaining = new HashSet<Employee>();
            }

            remaining.add(feedback.getEvaluated());

            lazyEvaluators.put(feedback.getEvaluator(), remaining);
        }
    }

    public void sendMails() throws MessagingException {

        for (Entry<Employee, Set<Employee>> entry : lazyEvaluators.entrySet()) {

            singleMailSender(entry);

        }
    }

    /**
     * @param entry
     */
    private void singleMailSender(final Entry<Employee, Set<Employee>> entry) {
        MimeMessagePreparator preparator = new MimeMessagePreparator() {
            public void prepare(final MimeMessage mimeMessage) throws Exception {
                MimeMessageHelper message = new MimeMessageHelper(mimeMessage, "ISO-8859-1");
                message.setSubject("Evaluaciones Pendientes - Recordatorio");
                message.setTo(entry.getKey().getPerson().getContactInfo().getEmail());

                message.setFrom("hrs@hexacta.com");
                Map model = new HashMap();
                model.put("evaluator", entry.getKey());
                model.put("evaluatedList", entry.getValue());
                String text = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine,
                        "com/hexacta/hrs/web/struts/actions/feedbacks/reminder-mail.vm", model);
                message.setText(text, true);
            }
        };
        mailSender.send(preparator);

    }

    /* Getters and Setters */

    /**
     * @return the roles
     */
    public String[] getRoles() {
        return roles;
    }

    /**
     * @param selectedRoles
     */
    public void setRoles(final String[] selectedRoles) {
        roles = selectedRoles;
    }

    /**
     * @param feedbackService
     *            the feedbackService to set
     */
    public void setFeedbackService(final FeedbackService feedbackService) {
        this.feedbackService = feedbackService;
    }

    public void setMailSender(final JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    /**
     * @param velocityEngine
     *            the velocityEngine to set
     */
    public void setVelocityEngine(final VelocityEngine velocityEngine) {
        this.velocityEngine = velocityEngine;
    }
}
